home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / t3d.pro < prev    next >
Text File  |  1997-07-08  |  6KB  |  205 lines

  1. ; $Id: t3d.pro,v 1.5 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1987-1997, Research Systems, Inc.  All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5.  
  6. PRO t3d, TRANSLATE = trans, SCALE = scale, ROTATE=rota, $
  7.     RESET = reset, PERSPECTIVE = pers, OBLIQUE = oblique, $
  8.     XYEXCH = xyexch, XZEXCH = xzexch, YZEXCH = yzexch, $
  9.     MATRIX = mat
  10. ;+
  11. ; NAME:
  12. ;    T3D
  13. ;
  14. ; PURPOSE:
  15. ;    Implement three-dimensional transforms.
  16. ;
  17. ;    This routine accumulates one or more sequences of translation,
  18. ;    scaling, rotation, perspective, and oblique transformations
  19. ;    and stores the result in !P.T, the 3D transformation system variable.
  20. ;    All the IDL graphic routines use this [4,4] matrix for output.
  21. ;
  22. ; CATEGORY:
  23. ;    Graphics.
  24. ;
  25. ; CALLING SEQUENCE:
  26. ;    T3D [, /RESET, TRANSLATE = T, SCALE = S, ROTATE = R, ... ]
  27. ;
  28. ; INPUTS:
  29. ;    No non-keyword inputs.
  30. ;
  31. ; KEYWORDS:
  32. ;    All inputs to T3D are in the form of keywords.  Any, all, or none of 
  33. ;    the following keywords can be present in a call to T3D.  The order of 
  34. ;    the input parameters does not matter.
  35. ;
  36. ;    The transformation specified by each keyword is performed in the
  37. ;    order of their descriptions below (e.g., if both TRANSLATE and
  38. ;    SCALE are specified, the translation is done first):
  39. ;
  40. ;    RESET:    Set this keyword to reset the transformation to the default 
  41. ;        identity matrix.
  42. ;
  43. ;    TRANSLATE:    A three-element vector of the translations in the X, Y, and Z 
  44. ;        directions.
  45. ;
  46. ;    SCALE:    A three-element vector of scale factors for the X, Y, and Z 
  47. ;        axes.
  48. ;
  49. ;       ROTATE:    A three-element vector of the rotations, in DEGREES, 
  50. ;        about the X, Y, and Z axes.  Rotations are performed in the
  51. ;        order of X, Y, and then Z.
  52. ;
  53. ;  PERSPECTIVE:    Perspective transformation.  This parameter is a scalar (p) 
  54. ;        that indicates the Z distance of the center of the projection.
  55. ;        Objects are projected into the XY plane at Z=0, and the "eye" 
  56. ;        is at point [0,0,p].
  57. ;
  58. ;      OBLIQUE:    A two-element vector of oblique projection parameters.
  59. ;        Points are projected onto the XY plane at Z=0 as follows:
  60. ;            x' = x + z(d COS(a)), and y' = y + z(d SIN(a)).
  61. ;        where OBLIQUE[0] = d, and OBLIQUE[1] = a.
  62. ;
  63. ;    XYEXCH:    Exchange the X and Y axes.
  64. ;
  65. ;    XZEXCH:    Exchange the X and Z axes.
  66. ;
  67. ;    YZEXCH:    Exchange the Y and Z axes.
  68. ;
  69. ;    MATRIX: Input/Output, If supplied as a 4 x 4 matrix on input,
  70. ;        MATRIX contains the starting transformation matrix.  
  71. ;        If supplied as either a non-zero scalar, or as a 4x4
  72. ;        matrix, the result is returned in this parameter and
  73. ;        !P.T is not modified.
  74. ;
  75. ; OUTPUTS:
  76. ;    The 4 by 4 transformation matrix !P.T is updated with the
  77. ;    resulting transformation, unless the keyword MATRIX is supplied,
  78. ;    in which case the result is returned in MATRIX and !P.T is
  79. ;    not affected. 
  80. ;    !P.T3D is NOT set, so for the transformations to have effect you
  81. ;    must set !P.T3D = 1 (or set the T3D keyword in subsequent calls
  82. ;    to graphics routines).
  83. ;
  84. ; COMMON BLOCKS:
  85. ;    None.
  86. ;
  87. ; SIDE EFFECTS:
  88. ;    !P.T is changed if the keyword MATRIX is not set.
  89. ;
  90. ; RESTRICTIONS:
  91. ;    This routine implements general rotations about the three axes.
  92. ;    The routines SURFACE and SHADE_SURF may only be used in conjunction 
  93. ;    with T3D rotations that project the Z axis in 3 dimensions to
  94. ;    a line parallel to the Y axis in 2 dimensions.
  95. ;
  96. ; PROCEDURE:
  97. ;    This program follows that of Foley & Van Dam, "Fundamentals of
  98. ;    Interactive Computer Graphics", Chapter 8, "Viewing in Three
  99. ;    Dimensions".
  100. ;
  101. ;    The matrix notation is reversed from the normal IDL sense,
  102. ;    i.e., here, the first subscript is the column, the second is the row,
  103. ;    in order to conform with the above reference.
  104. ;
  105. ;    A right-handed system is used.  Positive rotations are COUNTER-
  106. ;    CLOCKWISE when looking from a positive axis to the origin.
  107. ;
  108. ; EXAMPLES:
  109. ;    To reset the transformation, rotate 30 degs about the X axis
  110. ;    and do perspective transformation with the center of the projection
  111. ;    at Z = -3, X=0, and Y=0, enter:
  112. ;
  113. ;        T3D, /RESET, ROT = [ 30,0,0], PERS = 3.
  114. ;
  115. ;    Transformations may be cascaded, for example:
  116. ;
  117. ;        T3D, /RESET, TRANS = [-.5,-.5,0], ROT = [0,0,45]
  118. ;        T3D, TRANS = [.5,.5,0]
  119. ;
  120. ;    The first command resets, translates the point [.5,.5,0] to the 
  121. ;    center of the viewport, then rotates 45 degrees counterclockwise 
  122. ;    about the Z axis.  The second call to T3D moves the origin back to 
  123. ;    the center of the viewport.
  124. ;
  125. ; MODIFICATION HISTORY:
  126. ;    DMS, Nov, 1987.
  127. ;
  128. ;    DMS, June 1990.    Fixed bug that didn't scale or translate
  129. ;            matrices with perspective properly.
  130. ;    DMS, July, 1996.  Added MATRIX keyword.
  131. ;-
  132.  
  133. on_error,2              ;Return to caller if an error occurs
  134. id = fltarr(4,4)    ;Make identity matrix
  135. for i=0,3 do id[i,i]= 1.0
  136.  
  137. if keyword_set(reset) then a = id $    ; Start from identity?
  138. else if n_elements(mat) eq 16 then a = mat $    ;Use given transform
  139. else a = !p.t        ;Use existing transform
  140.  
  141. if n_elements(trans) ne 0 then begin    ;Translate?
  142.     ri = id
  143.     for i=0,2 do ri[3,i] = trans[i]
  144.     a = a # ri            ;Apply translation
  145.     endif
  146.  
  147. if n_elements(scale) ne 0 then begin    ;Scale
  148.     ri = id
  149.     for i=0,2 do ri[i,i] = scale[i]
  150.     a = a # ri            ;Apply scale
  151.     endif
  152.  
  153. if n_elements(rota) ne 0 then begin    ;Rotate?
  154.     ri = id[0:2,0:2]        ;Use 3 by 3's
  155.     r = ri
  156.     sx = sin(rota/!radeg) & cx = cos(rota/!radeg)
  157.  
  158.     if rota[0] ne 0.0 then begin    ;X Angle
  159.         r[1,1] = cx[0] & r[1,2] = sx[0]
  160.         r[2,1] = -sx[0] & r[2,2] = cx[0]
  161.         endif
  162.     if rota[1] ne 0 then begin    ;Y angle
  163.         rr = ri
  164.         rr[0,0] = cx[1] & rr[0,2] = -sx[1]
  165.         rr[2,0] = sx[1] & rr[2,2] = cx[1]
  166.         r =  r # rr
  167.         endif
  168.     if rota[2] ne 0 then begin    ;Z angle
  169.         rr = ri
  170.         rr[0,0]= cx[2] & rr[0,1] = sx[2]
  171.         rr[1,0] = -sx[2] & rr[1,1] = cx[2]
  172.         r =  r # rr
  173.         endif
  174.     rr = fltarr(4,4) 
  175.     rr[0,0] = r & rr[3,3]=1.0
  176.     a = a # rr            ;Apply cumulative rot transforms
  177.     endif
  178.  
  179. if n_elements(pers) ne 0 then begin    ;Perspective?
  180.     r = id
  181.     r[2,3] = -1./pers
  182.     a = a # r
  183.     endif
  184.  
  185. if n_elements(oblique) ne 0 then begin  ;Oblique projection?
  186.     r = id
  187.     r[2,2]=0.0
  188.     r[2,0] = oblique[0] * cos(oblique[1]/ !radeg)
  189.     r[2,1] = oblique[0] * sin(oblique[1]/ !radeg)
  190.     a = a # r
  191.     endif
  192.  
  193. if keyword_set(xyexch) then exch = [0,1]    ;Code to exchange axes.
  194. if keyword_set(xzexch) then exch = [0,2]
  195. if keyword_set(yzexch) then exch = [1,2]
  196. if n_elements(exch) ne 0 then begin    ;Exchange axes.
  197.     t = a[exch[0],*]
  198.     a[exch[0],0] = a[exch[1],*]
  199.     a[exch[1],0] = t
  200.     endif
  201.  
  202. if KEYWORD_SET(mat) then mat = a $    ;Save final projection
  203. else !p.t =  a
  204. end
  205.